#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include "../modules/ivi_ioctl.h"

int main(int argc, char *argv[]) {
	char v4dev[IVI_IOCTL_LEN], v6dev[IVI_IOCTL_LEN];
	int retval, fd, temp;
	unsigned short ratio, adjacent;
	struct in_addr v4addr;
	
	printf("IVI44 netfilter device controller utility v1.3\n");
	
	if ((fd = open("/dev/ivi44", 0)) < 0) {
		printf("Error: cannot open virtual device for ioctl, code %d.\n", fd);
		exit(-1);
	}

	if ((argc == 7) && (strcmp(argv[1], "start") == 0)) {
		// Set dev
		strncpy(v4dev, argv[2], IVI_IOCTL_LEN);
		strncpy(v6dev, argv[3], IVI_IOCTL_LEN);
		if ((retval = ioctl(fd, IVI_IOC_V4DEV, v4dev)) < 0) {
			printf("Error: failed to set IPv4 private device, code %d.\n", retval);
			exit(-1);
		}
		if ((retval = ioctl(fd, IVI_IOC_V6DEV, v6dev)) < 0) {
			printf("Error: failed to set IPv4 public device, code %d.\n", retval);
			exit(-1);
		}

		// Set v4 public address for nat44
		if ((retval = inet_pton(AF_INET, argv[4], (void*)(&v4addr))) != 1) {
			printf("Error: failed to parse IPv4 public address, code %d.\n", retval);
			exit(-1);
		}
		if ((retval = ioctl(fd, IVI_IOC_V4PUB, &(v4addr.s_addr))) < 0) {
			printf("Error: failed to set IPv4 public address, code %d.\n", retval);
			exit(-1);
		}

		ratio = atoi(argv[5]);
		adjacent = atoi(argv[6]);
		if ((retval = ioctl(fd, IVI_IOC_RATIO, &ratio)) < 0) {
			printf("Error: failed to set ratio parameter, code %d.\n", retval);
			exit(-1);
		}
		if ((retval = ioctl(fd, IVI_IOC_ADJACENT, &adjacent)) < 0) {
			printf("Error: failed to set adjacent parameter, code %d.\n", retval);
			exit(-1);
		}
		
		// Start ivi
		if ((retval = ioctl(fd, IVI_IOC_START, 0)) < 0) {
			printf("Error: failed to start IVI module, code %d.\n", retval);
			exit(-1);
		}
		
		printf("Info: successfully started IVI44 module.\n");
	}
	else if ((argc == 2) && (strcmp(argv[1], "stop") == 0)) {
		if ((retval = ioctl(fd, IVI_IOC_STOP, 0)) != 0) {
			printf("Error: failed to stop IVI module, code %d.\n", retval);
		}
		else {
			printf("Info: successfully stopped IVI module.\n");
		}
	}
	else {
		printf("Usage: ivictl start [private_dev] [public_dev] [public_network_prefix] [ratio] [adjacent]\n");
		printf("       ivictl stop\n");
	}

	close(fd);

	return retval;
}
